﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using AspectCore.Configuration;
using AspectCore.Extensions.DependencyInjection;
using ConsoleAppTemp.AspectCore;
using FDSimpleModelGenerator.ImageCode;
using Microsoft.Extensions.DependencyInjection;

namespace ConsoleAppTemp
{
    class Program
    {
        static void Main(string[] args)
        {
            BasicImageCode bc = new BasicImageCode();
            var res = bc.RandCode(8, 3);

            bc.CreateImage();
            Console.WriteLine(bc.Code);
            bc.Image.Save("imgcode.jpg", ImageFormat.Jpeg);
            Console.WriteLine(res);


            var cbeg = 0x4E00;
            var cend = 0x9FA5;
            for (var i = cbeg; i < cend; ++i)
            {
                Console.Write((char)i);
            }

            Console.Read();
        }

        static void Main3(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddTransient<ICustomService, CustomService>();
            services.ConfigureDynamicProxy(config =>
            {
                config.Interceptors.AddTyped<CustomInterceptorAttribute>(method =>
                    {
                        return !method.Name.EndsWith("Me");
                    });
            });

            var container = services.BuildAspectInjectorProvider();

            var customerSerivce = (ICustomService)container.GetService(typeof(ICustomService));
            customerSerivce.Call();
            customerSerivce.HelpMe();

            var result = customerSerivce.Get();



            Console.Read();
        }

        static void Main1(string[] args)
        {
            var lines = File.ReadAllLines("keywords.txt", Encoding.UTF8);
            var keywords = new List<string>();
            foreach (var line in lines)
            {
                if (IsNeedSave(line, out string keyword))
                    keywords.Add(keyword);
            }
            Console.WriteLine($"\"{string.Join("\",\"", keywords)}\"");
            Console.Read();
        }

        static bool IsNeedSave(string line, out string keyword)
        {
            keyword = string.Empty;
            if (string.IsNullOrEmpty(line))
                return false;
            var items = line.Split(new[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
            if (items.Length < 3)
            {
                return false;
            }

            keyword = items[0].Trim();
            return items.Count(c => c.Trim().Equals("保留")) >= 2;
        }

        static void Main2(string[] args)
        {
            ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>();

            Parallel.For(0, 10000, i =>
            {
                cd.AddOrUpdate(1, 1, (key, value) => value + 1);
            });
            Console.WriteLine("After 10000 AddOrUpdates, cd[1]={0}, should be 10000", cd[1]);


            ConcurrentDictionary<string, CacheItem> cache = new ConcurrentDictionary<string, CacheItem>();

            Parallel.For(0, 100, i =>
            {
                cache.AddOrUpdate(i.ToString(), new CacheItem(i, TimeSpan.FromSeconds(5)),
                    (key, value) => new CacheItem(i, TimeSpan.FromSeconds(1)));
            });

            object sync = new object();
            Parallel.For(0, 100, i =>
                {
                    // 说明AddOrUpdate会有并发问题
                    //cache.AddOrUpdate("50", new CacheItem(500, TimeSpan.FromHours(1)),
                    //    (key, oldValue) => new CacheItem(i.ToString(), TimeSpan.FromMinutes(10)));

                    var key = "50";
                    Console.WriteLine(i);
                    lock (sync)
                    {
                        cache[key] = new CacheItem(i.ToString(), TimeSpan.FromMinutes(10));
                    }

                    //cache.AddOrUpdate("50", new CacheItem(500, TimeSpan.FromHours(1)),
                    //    (key, oldValue) =>
                    //    {
                    //        oldValue.Set(i.ToString(), TimeSpan.FromMinutes(10));
                    //        return oldValue;
                    //    });
                });

            var c50 = cache["50"];
            Console.WriteLine("After 100 AddOrUpdates, cache[\"50\"]={0}, should be 100", c50);


            Console.ReadLine();
        }
    }

    class CacheItem
    {
        private object Data
        {
            get
            {
                if (Expires > DateTime.Now)
                {
                    return _data;
                }

                return null;
            }
        }

        private DateTime Expires { get; set; }

        public TimeSpan ExpireTime { get; private set; }

        private object _data;

        public CacheItem(object data, TimeSpan expires)
        {
            //_data = data;
            //ExpireTime = expires;
            //Expires = DateTime.Now + expires;
            Set(data, expires);
        }

        public CacheItem()
        {
        }

        public void Set(object data, TimeSpan expires)
        {
            _data = data;
            ExpireTime = expires;
            Expires = DateTime.Now + expires;
        }

        public bool IsEmpty => Expires == DateTime.MinValue;

        public override string ToString()
        {
            return $"{Data},{Expires},{IsEmpty}";
        }
    }
}
